#if NVP
/*
 * Copyright 2006 PayPal, Inc. All Rights Reserved.
 */
using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using com.paypal.sdk.exceptions;
using com.paypal.sdk.profiles;
using com.paypal.sdk.rules;
using com.paypal.sdk.util;

namespace com.paypal.sdk.core.nvp
{
	/// <summary>
	/// Summary description for NVPAPICaller.
	/// </summary>
	public class NVPAPICaller : APICallerBase
	{
		private string pendpointurl = string.Empty;
		private X509Certificate x509;
		private const string CVV2 = "CVV2";
		private const string SIGNATURE = "SIGNATURE";
		private const string PWD = "PWD";
		private const string ACCT = "ACCT";
		private static readonly string[] SECURED_NVPS = new string[] {ACCT, CVV2, SIGNATURE, PWD};

		/// <summary>
		/// Main Call Method that fo API calls
		/// </summary>
		/// <param name="NvpRequest"></param>
		/// <returns></returns>
		public string Call(string NvpRequest) //CallNvpServer
		{
			this.validateProfile(this.Profile);
			string url = pendpointurl;
			//To Add the credentials from the profile
			string strPost = NvpRequest + "&" +
			                 buildCredentialsNVPString(Profile,NvpRequest);

			string result;
			try
			{
				if(this.Profile is PermissionAPIProfile)
					result = Utils.HttpPost(url, strPost, this.Profile.Timeout, this.Profile is PermissionAPIProfile ? x509 : null, this.Profile);
				else
					result = Utils.HttpPost(url, strPost, this.Profile.Timeout, this.Profile is CertificateAPIProfile ? x509 : null);
			}
			catch (Exception e)
			{
				throw new FatalException(e.Message);
			}

			return result;
		}
		/// <summary>
		/// Validate profile
		/// </summary>
		/// <param name="profile"></param>
		protected override void validateProfile(IAPIProfile profile)
		{
			if ((profile is SignatureAPIProfile ) ||(profile is CertificateAPIProfile))
			{
				ValidationErrors errors = new ValidationErrors();
				if (profile is CertificateAPIProfile)
				{
					if (Utils.IsEmpty(profile.CertificateFile))
					{
						errors.Add(new ValidationError(MessageResources.GetMessage("API_CERTIFICATE_FILE_EMPTY")));
					}

					if (Utils.IsEmpty(profile.PrivateKeyPassword))
					{
						errors.Add(new ValidationError(MessageResources.GetMessage("API_PRIVATE_KEY_PASSWORD_EMPTY")));
					}
				}
				if (!errors.IsEmpty())
				{
					StringBuilder msg = new StringBuilder(MessageResources.GetMessage("PROFILE_INVALID"));
					IEnumerator iEnum = errors.GetEnumerator();
					while (iEnum.MoveNext())
					{
						ValidationError error = (ValidationError) iEnum.Current;
						msg.Append("\n" + error.Key);
					}
					throw new TransactionException(msg.ToString());
				}
			}
		}

		/// <summary>
		/// Reading endpoint and certificates are done in SetupConnection
		/// </summary>
		/// <param name="cprofile"></param>
		protected override void SetupConnection(IAPIProfile cprofile)
		{       bool stage = false;
		       
			string environment = cprofile.Environment;
			stage  = Utils.IsStage(environment);
			
			if (stage) {
			    pendpointurl = "https://api."+environment+".paypal.com/nvp";
			} else {
			
			
				Endpoint endpoint =
					Config.Instance.GetEndpoint(environment, MessageResources.GetMessage("NVPPORT"), cprofile is SignatureAPIProfile);

				if (endpoint != null && endpoint.Url != null)
				{
					pendpointurl = endpoint.Url;
				}
				else
				{
					throw new TransactionException(MessageResources.GetMessage("ENDPOINT_NOT_FOUND"));
				}
			}
			if (cprofile is CertificateAPIProfile)
			{
				x509 = GetCertificate(cprofile.APIUsername);
			}

			if (cprofile is PermissionAPIProfile && (cprofile.CertificateFile !=null && cprofile.CertificateFile.Length>0))
			{
				x509 = GetCertificate(cprofile.APIUsername);
			}
		} // SetupConnection

		/// <summary>
		/// Credentials added to the NVP string
		/// </summary>
		/// <param name="profile"></param>
		/// <returns></returns>
		private static string buildCredentialsNVPString(IAPIProfile profile,string nvprequest)
		{

			NVPCodec codec = new NVPCodec();
			if (profile is SignatureAPIProfile && !Utils.IsEmpty(profile.APISignature))
			{
				if (!Utils.IsEmpty(profile.APIUsername))
					codec["USER"] =  profile.APIUsername;
				if (!Utils.IsEmpty(profile.APIPassword))
					codec[PWD] =  profile.APIPassword;
				if (profile is SignatureAPIProfile && !Utils.IsEmpty(profile.APISignature))
					codec[SIGNATURE] =  profile.APISignature;
				if (!Utils.IsEmpty(profile.Subject))//.Subject
					codec["SUBJECT"] =  profile.Subject;
			}
			else if (profile is UniPayAPIProfile)
			{
				if (!Utils.IsEmpty(profile.getFirstPartyEmail))//.Subject
					codec["SUBJECT"] =  profile.getFirstPartyEmail;
			}
			else
			{
				if (!Utils.IsEmpty(profile.APIUsername))
					codec["USER"] =  profile.APIUsername;
				if (!Utils.IsEmpty(profile.APIPassword))
					codec[PWD] =  profile.APIPassword;
				if (!Utils.IsEmpty(profile.Subject))//.Subject
					codec["SUBJECT"] =  profile.Subject;

			}

			//}
			
			if(nvprequest.ToUpper().IndexOf("VERSION=") == -1)
				codec["VERSION"] =  MessageResources.GetMessage("WSDLVERSION");

			codec["SOURCE"] =  MessageResources.GetMessage("SOURCE");
			return codec.Encode();
		}
	}
}

#endif